﻿using System;

namespace Fadd.Components
{
	/// <summary>
	/// Used to define components.
	/// </summary>
	public class ComponentAttribute : Attribute
	{
		/// <summary>
		/// Initializes a new instance of the <see cref="ComponentAttribute"/> class.
		/// </summary>
		/// <param name="interfaceType">Interface that this component is an instance for.</param>
		public ComponentAttribute(Type interfaceType) : this(interfaceType, 0, null)
		{
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="ComponentAttribute"/> class.
		/// </summary>
		/// <param name="interfaceType">Interface that this component is an instance for.</param>
		/// <param name="flags">Kind of component</param>
		public ComponentAttribute(Type interfaceType, ComponentFlags flags)
			: this(interfaceType, 0 , null)
		{
			Flags = flags;
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="ComponentAttribute"/> class.
		/// </summary>
		/// <param name="interfaceType">Interface that this component is an instance for.</param>
		/// <param name="version">Component version.</param>
		public ComponentAttribute(Type interfaceType, int version)
			: this(interfaceType, version, null)
		{
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="ComponentAttribute"/> class.
		/// </summary>
		/// <param name="interfaceType">Interface that this component is an instance for.</param>
		/// <param name="runAt">Where the component should be running.</param>
		public ComponentAttribute(Type interfaceType, string runAt) : this(interfaceType, 0, runAt)
		{
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="ComponentAttribute"/> class.
		/// </summary>
		/// <param name="interfaceType">Interface that this component is an instance for.</param>
		/// <param name="version">Component version.</param>
		/// <param name="runAt">Where the component should be running.</param>
		public ComponentAttribute(Type interfaceType, int version, string runAt)
		{
			InterfaceType = interfaceType;
			RunAt = runAt;
			Version = version;
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="ComponentAttribute"/> class.
		/// </summary>
		/// <param name="interfaceType">Interface that this component is an instance for.</param>
		/// <param name="version">Component version.</param>
		/// <param name="runAt">Where the component should be running.</param>
		/// <param name="flags">Flags specifying behavior.</param>
		public ComponentAttribute(Type interfaceType, int version, string runAt, ComponentFlags flags)
		{
			InterfaceType = interfaceType;
			RunAt = runAt;
			Flags = flags;
			IsFlagsSpecified = true;
			Version = version;
		}

		/// <summary>
		/// Gets or sets where component should be running.
		/// </summary>
		/// <remarks>
		/// Can be used to specify that this instance should only be added/created
		/// as a specific location (such as in a server or client).
		/// </remarks>
		public string RunAt { get; set; }

		/// <summary>
		/// Gets or sets component flags
		/// </summary>
		public ComponentFlags Flags { get; set; }

		/// <summary>
		/// Gets or sets version of the component.
		/// </summary>
		/// <remarks>
		/// Can be used to replace an earlier version of a component implementation
		/// with a later one.
		/// </remarks>
		public int Version { get; set; }

		/// <summary>
		/// Gets or sets interface that this is an instance for.
		/// </summary>
		public Type InterfaceType { get; set; }

		internal bool IsFlagsSpecified { get; private set; }
	}
}
